package com.tuu.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tuu.configBean.RedisUtil;
import com.tuu.mapper.JwtUserMapper;
import com.tuu.pojo.JwtClainsObject;
import com.tuu.pojo.JwtUser;
import com.tuu.utils.JwtTokenUtil;
import com.tuu.utils.MyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@Service
public class UserServiceImpl implements UserService{


    @Autowired
    private JwtUserMapper jwtUserMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private MyUtils myUtils;
    //token的有效时间 20分钟 可以自定义
    @Value("${jwt.expiration}")
    String exp;
    //生成token会同时生成 用户版本号 此用户版本号和 redis中的
    //权限版本号相同 ,当检测到这两个版本号不同时,说明数据库权限表有变化,
    //这时需要重新从数据库拿最新的用户权限,放到redis
    @Value("${jwt.userVersionExpiration}")
    String userExp;
    //权限版本号名称 在redis中的key
    @Value("${jwt.pVersionName}")
    String pVersionName;
    //用户标识  传给前端生成cookie 检验token时从request中拿到
    //这个cookie,看和token中的claims中的是否相等,
    // 不相等说明这个token可能黑客从用户那里盗取的
    //这个cookie的名字可以在application.yml中配置
    @Value("${jwt.userIdentifier}")
    String userIdent;
    //假的用户标识, 将真的混在其中,也可以在application.yml配置
    //个数,名字都可以自定义
    @Value("${jwt.userIdentFakes}")
    String userIdentFakes;
    @Override
    public Map<String,Object> login2(Map deviceInfo,JwtUser user) throws Exception {
        Map<String,Object> map=new HashMap<>();
        Map<String,Object> mapCookies=new HashMap<>();
        JwtUser user1 =new JwtUser();
        user1.setUsername(user.getUsername());
        //user1.setPass(user.getPassword());
        System.out.println(user.getUsername()+"-----"+user.getPassword());
        QueryWrapper qw = new QueryWrapper();
        qw.setEntity(user1);
        //qw.select("name","pass");//只查询age和name字段
        //从数据库查询用户  之后再比对密码
        JwtUser b = jwtUserMapper.selectOne(qw);
        String token=null;
        if(b!=null){  ////用的是security的BCryte加密  加密解密 比md5加密安全
            if(!passwordEncoder.matches(user.getPassword(),b.getPassword())){
                System.out.println("密码不匹配。。。");
                return null;
            }
            //将token的生成要素放在jco中
            JwtClainsObject jco=new JwtClainsObject();
            //jco.setRandomId(UUID.randomUUID().toString().replaceAll("-", ""));
            jco.setRandomId(myUtils.randomString(46));
            jco.setSubjectUid(b.getId());
            //5分钟 毫秒
            //jco.setTtlMillis(Constants.JwtConst.EXPMILLIS.getTimee());
            //jwt有效时间20分钟
            jco.setTtlMillis(Long.parseLong(exp));
            jco.setUsername(user.getUsername());
            //生成token
            token=jwtTokenUtil.generateToken2(jco);
            System.out.println("login2的token是"+token);
            try{
                //""+Constants.JwtConst.EXPMILLIS.getTimee()
                redisUtil.set("uid"+b.getId()+"token",token,Long.parseLong(exp)/1000L);
                redisUtil.set("uid"+b.getId()+"pVersion",(String)redisUtil.get(pVersionName),Long.parseLong(userExp)/1000L);
            }catch (Exception e){
                System.out.println("捕捉到redis错误。。。。");
                throw new PoolException("redis连接不行了");
            }
            //MyAesUtils.encrypt(b.getId(),"ppp");
            map.put("token",token);
            mapCookies.put("nickname",b.getUsername());
            mapCookies.put(userIdent,jco.getRandomId());
            String[] fakes=userIdentFakes.split(",");
            for(String f : fakes){
                mapCookies.put(f,myUtils.randomString(myUtils.GetRandomNum(5,46)));
            }
            map.put("cookies",mapCookies);
            //给uid加密
            //map.put("tmc",MyAesUtils.encrypt(b.getId(),Constants.JwtConst.AES16KEY.getValue()));
            //map.put("tmc",jco.getRandomId());
            System.out.println("正在返回cookies 在login页面");
            //清除request
            //GlobalMap.clear();
            //ObjectThreadLocal.remove();
        }
        return map;
    }
    @Override
    public void logout(String token, HttpServletRequest request) throws Exception{
        jwtTokenUtil.logoutJWT(token,request);
    }
}